// Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
package cci

import (
	"fleetmanager/api/model/fleet"
	"fmt"
)

const (
	namespaceApiVersion                = "v1"
	namespaceKind                      = "namespace"
	defaultNamespaceKubernetesIoFlavor = "general-computing"

	networkApiVersion  = "networking.cci.io/v1beta1"
	networkKind        = "Network"
	defaultNetworkType = "underlay_neutron"

	podApiVersion              = "v1"
	podKind                    = "Pod"
	defaultPodImagePullPolicy  = "Always"
	defaultPodContainerName    = "container-0"
	defaultPodImagePullSecrets = "imagepull-secret"
	defaultPodPriority         = 0
	defaultPodRestartPolicy    = "Always"
	defaultYangtseIoPodWithEip = "true"
)

//template
type InstancePodGroup struct {
	FleetId               string                      `json:"fleet_id"`
	MinInstanceNumber     int                         `json:"min_instance_number"`
	MaxInstanceNumber     int                         `json:"max_instance_number"`
	EnterpriseProjectId   string                      `json:"enterprise_project_id"`
	DesireInstanceNumber  int                         `json:"desire_instance_number"`
	CoolDownTime          int                         `json:"cool_down_time"`
	VpcId                 string                      `json:"vpc_id"`
	SubnetId              string                      `json:"subnet_id"`
	InstanceType          string                      `json:"instance_type"`
	PodTemplate           PodRequest                  `json:"pod_template"`
	InstanceConfiguration fleet.InstanceConfiguration `json:"instance_configuration"`
	EnableAutoScaling     bool                        `json:"enable_auto_scaling"`
	Agency                fleet.Agency                `json:"agency"`
	Name                  string                      `json:"instance_scaling_group_name"`
}

type CreatePodRequest struct {
	InstancePodGroup *InstancePodGroup
}

type PrepareForCreatePod struct {
	AuthorizationInfo *AuthorizationInfo
	NameSpaceRequest  *NameSpaceRequest
	NetWorkRequest    *NetWorkRequest
}

func BuildBasicPrepareForCreatePod() *PrepareForCreatePod {
	preRequest := &PrepareForCreatePod{
		AuthorizationInfo: &AuthorizationInfo{},
		NameSpaceRequest:  buildBasicNamespaceRequest(),
		NetWorkRequest:    buildBasicNetWorkRequest(),
	}
	return preRequest
}

func buildBasicNamespaceRequest() *NameSpaceRequest {
	namespace := &NameSpaceRequest{
		ApiVersion: namespaceApiVersion,
		Kind:       namespaceKind,
		Metadata: NameSpaceMetadata{
			Annotations: NamespaceAnnotations{
				NamespaceKubernetesIoFlavor: defaultNamespaceKubernetesIoFlavor,
			},
		},
	}
	return namespace
}

func buildBasicNetWorkRequest() *NetWorkRequest {
	network := &NetWorkRequest{
		ApiVersion: networkApiVersion,
		Kind:       networkKind,
	}
	return network
}
func (preRequest *PrepareForCreatePod) SetAuthorizationInfo(ak, sk, regionId string) {
	preRequest.AuthorizationInfo = &AuthorizationInfo{
		AK:       ak,
		SK:       sk,
		RegionId: regionId,
	}
}
func (preRequest *PrepareForCreatePod) SetNameSpace(namespaceName, namespaceFlavor, enterpriseId string) {
	if preRequest.NameSpaceRequest == nil {
		preRequest.NameSpaceRequest = buildBasicNamespaceRequest()
	}
	preRequest.NameSpaceRequest.Metadata.Name = namespaceName
	preRequest.NameSpaceRequest.Metadata.Annotations.NamespaceKubernetesIoFlavor = namespaceFlavor
	preRequest.NameSpaceRequest.Metadata.Labels.SysEnterpriseProjectId = enterpriseId
}

func (preRequest *PrepareForCreatePod) SetNetWorkMetadata(networkName, domainId, projectId, securityGroupId string) {
	if preRequest.NetWorkRequest == nil {
		preRequest.NetWorkRequest = buildBasicNetWorkRequest()
	}
	preRequest.NetWorkRequest.Metadata = NetWorkMetadata{
		Name: networkName,
		Annotations: NetworkAnnotations{
			NetworkAlphaKubernetesIoDomainId:             domainId,
			NetworkAlphaKubernetesIoProjectId:            projectId,
			NetworkAlphaKubernetesIoDefaultSecurityGroup: securityGroupId,
		},
	}
}

func (preRequest *PrepareForCreatePod) SetNetWorkSpec(vpcId, networkId, ipv4SubnetId string) {
	if preRequest.NetWorkRequest == nil {
		preRequest.NetWorkRequest = buildBasicNetWorkRequest()
	}
	preRequest.NetWorkRequest.Spec = NetWorkSpec{
		AttachedVPC: vpcId,
		NetworkID:   networkId,
		NetworkType: defaultNetworkType,
		SubnetID:    ipv4SubnetId,
	}
}

func (request *PodRequest) SetPodName(podName string) {
	request.Metadata.Name = podName
}

func (request *PodRequest) SetPodMetadataAnnotations(bandSize, networkType, eipChargeMode, bandwidthId string) {
	request.Metadata = PodMetadata{
		Annotations: PodMetadataAnnotations{
			YangtseIoPodWithEip:       defaultYangtseIoPodWithEip,
			YangtseIoEipBandwidthSize: bandSize,
			YangtseIoEipNetworkType:   networkType,
			YangtseIoEipChargeMode:    eipChargeMode,
			YangtseIoEipBandwidthId:   bandwidthId,
		},
	}
}

func (request *PodRequest) SetPodSpecContainer(env map[string]string, imageURL string, cpu, memory int, memoryUnit string) {
	var podEnv []PodSpecContainersEnv
	for key, value := range env {
		tmpEnv := PodSpecContainersEnv{
			Name:  key,
			Value: value,
		}
		podEnv = append(podEnv, tmpEnv)
	}
	podContainer := []PodSpecContainers{
		{
			Env:             podEnv,
			Image:           imageURL,
			ImagePullPolicy: defaultPodImagePullPolicy,
			Name:            defaultPodContainerName,
			Resources: PodSpecContainersResources{
				Limits: PodSpecContainersResourcesLimits{
					Cpu:    fmt.Sprintf("%v", cpu),
					Memory: fmt.Sprintf("%v%v", memory, memoryUnit),
				},
				Requests: PodSpecContainersResourcesRequests{
					Cpu:    fmt.Sprintf("%v", cpu),
					Memory: fmt.Sprintf("%v%v", memory, memoryUnit),
				},
			},
		},
	}
	request.Spec.Containers = podContainer
}

func BuildBasicPodRequest() *PodRequest {
	pod := &PodRequest{
		ApiVersion: podApiVersion,
		Kind:       podKind,
		Spec: PodSpec{
			ImagePullSecrets: []PodSpecImagePullSecrets{
				{
					Name: defaultPodImagePullSecrets,
				},
			},
			Priority:      defaultPodPriority,
			RestartPolicy: defaultPodRestartPolicy,
		},
	}
	return pod
}
